﻿Imports Lucene.Net.Analysis
Imports Aricie.DNN.Modules.LuceneSearch.Business
Imports Lucene.Net.Analysis.Tokenattributes

Namespace Aricie.DNN.Modules.LuceneSearch.Business

    Public Class SynonymFilter
        Inherits TokenFilter


        Private synonymTokenQueue As Queue(Of Token)
        Private _synonymEngine As ISynonymEngine

        Private termAtt As ITermAttribute
        Private posAtt As PositionIncrementAttribute
        Private currentSynonyms As Stack(Of String)
        Private currentState As State



        Property SynonymEngine() As ISynonymEngine
            Get
                Return _synonymEngine
            End Get
            Private Set(ByVal value As ISynonymEngine)
                _synonymEngine = value
            End Set
        End Property

        Public Sub New(ByVal input As TokenStream, ByVal synonymEngine As ISynonymEngine)
            MyBase.New(input)
            Me.synonymTokenQueue = New Queue(Of Token)
            If (synonymEngine Is Nothing) Then
                Throw New ArgumentNullException("synonymEngine")
            End If
            Me.SynonymEngine = synonymEngine

            termAtt = AddAttribute(Of Lucene.Net.Analysis.Tokenattributes.ITermAttribute)()
            posAtt = DirectCast(AddAttribute(Of Lucene.Net.Analysis.Tokenattributes.IPositionIncrementAttribute)(), PositionIncrementAttribute)
            currentSynonyms = New Stack(Of String)()
        End Sub


        Public Overrides Function IncrementToken() As Boolean
            ' Voir : http://www.opten.ch/blog/2014/05/30/writing-a-custom-synonym-token-filter-in-lucenenet/

            If currentSynonyms.Count > 0 Then
                Dim synonym As String = currentSynonyms.Pop()
                RestoreState(currentState)
                termAtt.SetTermBuffer(synonym)
                posAtt.PositionIncrement = 0
                Return True
            End If

            If Not input.IncrementToken() Then
                Return False
            End If

            Dim currentTerm As String = termAtt.Term

            If currentTerm IsNot Nothing Then
                Dim synonyms = Me.SynonymEngine.GetSynonyms(currentTerm)
                If synonyms Is Nothing Then
                    Return True
                End If
                For Each synonym As String In synonyms
                    currentSynonyms.Push(synonym.ToLower())
                Next
            End If
            currentState = CaptureState()
            Return True

        End Function
    End Class

End Namespace